package com.qdlc.p2p.biz.web.interceptor;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Strings;
import com.opensymphony.xwork2.ActionInvocation;
import com.qdlc.p2p.biz.service.LogService;
import com.qdlc.p2p.common.constant.Constant;
import com.qdlc.p2p.common.constant.LogType;
import com.qdlc.p2p.common.exception.BusinessException;
import com.qdlc.p2p.common.util.StringUtil;
import com.qdlc.p2p.common.util.ip.IPUtil;
import com.qdlc.p2p.dal.common.SystemConfigHelper;
import com.qdlc.p2p.dal.dto.Log;
import com.qdlc.p2p.dal.dto.Operator;
import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

public class ChannelInterceptor extends BaseInterceptor {

	private static final long serialVersionUID = 1L;

	private static final Logger log = Logger.getLogger(ChannelInterceptor.class);

	@Resource
	private LogService logService;

	private static final String MSG = "msg";

	private static final String NONE = "";

	protected HttpServletRequest request;

	private HttpServletResponse response;

	//推广传参
	private static final String PRA="pra";

	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		request = ServletActionContext.getRequest();
		response = ServletActionContext.getResponse();
		String actionName = invocation.getInvocationContext().getName();
		String className = invocation.getAction().getClass().getName();
		String pra = getParameterByName(PRA);
		try {
			// PS 进行注册时,如果来自渠道,则跳转到渠道注册页面。 如类变更则需要修改些代码
			String channelName = null;
			if ((channelName = getChannelName()) != null&&getChannelName()!="" && "register".equals(actionName)&& "com.qd.p2p.web.action.user.UserRegistAction".equals(className)) {
				channelName = channelName.trim();
				response.sendRedirect(SystemConfigHelper.getValue(SystemConfigHelper.Nid.CHANNEl_REG) + ("true".equals(channelName) ? "" : ("_" + channelName)));
				return null;
			}if("com.qd.p2p.web.action.InvestAction".equals(className)&&"index".equals(actionName)&&!Strings.isNullOrEmpty(pra)) {
				addCookie("__pra", pra);
				return invocation.invoke();
			} else{
				return invocation.invoke();
			}
		} catch (BusinessException e) {
			log.error(actionName, e);
			saveExceptionLog(actionName);
			if (e.getType() != BusinessException.TYPE_JSON) {
				message(e);
				return MSG; // 这里要分 前台 和 后台
			} else {
				Map<String, Object> data = new HashMap<String, Object>();
				data.put("result", false);
				data.put("msg", e.getMessage());
				data.put("url", e.getUrl());
				data.put("err_code", e.getErrorCode());
				printJson(JSON.toJSONString(data));
				return null;
			}
		} catch (Exception e) {
			log.error(actionName, e);
			saveExceptionLog(actionName);
			message("抱歉，出现异常，请联系平台客服人员！", NONE);
			return MSG; // 这里要分 前台 和 后台
		}
	}

	public void message(BusinessException e) {
		String url = e.getUrl();
		String msg = e.getMessage();
		String buttonName = e.getButtonName();
		HttpServletRequest request = ServletActionContext.getRequest();
		String urlBack;
		if (e.getType() == 0) {
			if (StringUtil.isNotBlank(url)) {
				if (StringUtil.isNotBlank(buttonName)) {
					urlBack = "<a href='" + url + "'>" + buttonName + "</a>";
				} else {
					urlBack = "<a href='" + url + "'>返回</a>";
				}

			} else {
				urlBack = "<a href='javascript:history.go(-1)'>返回</a>";
			}
		} else {
			urlBack = "<a href='javascript:history.go(-1)'>返回</a>";
		}

		request.setAttribute("backurl", urlBack);
		if (msg == null) {
			msg = "";
		}
		request.setAttribute("rsmsg", msg);
	}

	/**
	 * 异常信息保存
	 *
	 * @param methodName 方法名
	 */
	public void saveExceptionLog(String methodName) {
		StringWriter sw = new StringWriter();
		Log log = new Log();
		log.setMethod(methodName);
		log.setException(sw.toString());
		log.setParams(this.getAllParams(true));
		String path = request.getServletPath();
		String ip = IPUtil.getRemoteIP(request);
		log.setRemoteAddr(ip);
		log.setRequestUri(path);
		log.setType(LogType.TYPE_EXCEPTION);
		if (request.getSession() != null) {
			Operator op = (Operator) request.getSession().getAttribute(Constant.SESSION_OPERATOR);
			if (op != null) {
				log.setAddUser(op.getName());
			}
		}
		logService.addLog(log);
	}

	/**
	 * 提取参数
	 *
	 * @param safety 是否对密码过滤
	 * @return 参数信息
	 */
	protected String getAllParams(boolean safety) {
		StringBuffer ps = new StringBuffer();
		Enumeration<?> parameterNames = request.getParameterNames();
		while (parameterNames.hasMoreElements()) {
			String parameter = (String) parameterNames.nextElement();
			String value = request.getParameter(parameter);
			if (StringUtil.isNotBlank(value)) {
				if (!safety || (safety && !parameter.contains("password") && !parameter.contains("pwd"))) { // 安全性
					ps.append(parameter + "=" + value);
					if (parameterNames.hasMoreElements()) {
						ps.append("&");
					}
				}
			}
		}
		return ps.toString();
	}

	/**
	 * 来自渠道引流
	 */
	private String getChannelName() {
		String pidKey = "pid";
		String pid = getCookieByKey("__pid");
		String paramId = getParameterByName(pidKey);
		// cookie中存在
		if (!Strings.isNullOrEmpty(pid) && (pid.equals(paramId) || Strings.isNullOrEmpty(paramId))) {
			return pid;
		}
		if (!Strings.isNullOrEmpty(paramId)) {
			addCookie("__pid", paramId);
		}
		return paramId;
	}

	/**
	 * 来自渠道引流
	 */
	private boolean isFromChannel() {
		String pidKey = "pid";
		String pid = getCookieByKey("__pid");
		// cookie中存在
		if (!Strings.isNullOrEmpty(pid)) {
			return true;
		} else {
			pid = getParameterByName(pidKey);
			// 保存到cookie中
			if (!Strings.isNullOrEmpty(pid)) {
				addCookie("__pid", pid);
				return true;
			}
		}
		return false;
	}

	private String getParameterByName(String key) {
		Object values = request.getParameterMap().get(key);
		if (values instanceof String[]) {
			return ((String[]) values)[0];
		}
		return "";
	}

	private void addCookie(String key, String val) {
		HttpServletResponse response = ServletActionContext.getResponse();
		// 清空cookie
		Cookie cookie = new Cookie(key, val);
		cookie.setMaxAge(8 * 3600);
		try {
			URI uri = new URI(SystemConfigHelper.getValue(SystemConfigHelper.Nid.WEB_URL));
			cookie.setDomain(uri.getHost());
			cookie.setPath("/");
			response.addCookie(cookie);
		} catch (URISyntaxException e) {
			e.printStackTrace();
		}
	}

	private String getCookieByKey(String key) {
		if (request == null) {
			return "";
		}
		Cookie[] cookies = request.getCookies();
		if (cookies != null) {
			for (Cookie cookie : cookies) {
				if (cookie == null) {
					return "";
				}
				String name = cookie.getName();
				if (key.equals(name)) {
					return cookie.getValue();
				}
			}
		}
		return "";
	}
}